import numpy as np
import matplotlib.pyplot as plt


def point_to_segment_distance(vector1, vector2, point):
    """
    Computes the squared distance from a line segment with the specified endpoints to a specified point.

    Args:
        vector1 (Vector2): The first endpoint of the line segment.
        vector2 (Vector2): The second endpoint of the line segment.
        point (Vector2): The point to which the squared distance is to be calculated.

    Returns:
        float: The squared distance from the line segment to the point.
    """
    # Compute squared length of the line segment
    line_length_sq = np.dot(vector2 - vector1, vector2 - vector1)

    # If line_length_sq is zero, the segment is a point
    if line_length_sq == 0:
        return np.dot(point - vector1, point - vector1)

    # Compute the projection parameter of the point onto the line
    t = max(0, min(1, np.dot(point - vector1, vector2 - vector1) / line_length_sq))

    # Compute the closest point on the line segment
    closest_point = vector1 + t * (vector2 - vector1)

    # Return the squared distance between the point and the closest point on the line segment
    return np.dot(point - closest_point, point - closest_point)


def circle_line_intersect(center, radius, line_coords):
    """
    判断圆与线段是否相交或接触

    参数:
    center: 圆心坐标 (x, y)
    radius: 圆的半径
    line_coords: 线段端点坐标 ps, p2

    返回值:
    如果圆和线段相交或接触，返回True；否则，返回False。
    """
    # 计算点到线段的距离的平方
    distance_sq = point_to_segment_distance(np.array(line_coords[0]), np.array(line_coords[1]), np.array(center))

    # 如果距离的平方小于等于圆的半径的平方，说明相交或接触
    return distance_sq < radius * radius


# 示例用法:
center = np.array((0, 0))
radius = 3.0
line_coords = [np.array((-0.0, 2.0)), np.array((10.0, 3.0))]

# 判断圆与线段是否相交
result = circle_line_intersect(center, radius, line_coords)
print("Intersection:", result)  # 输出: True

# 绘制图形
fig, ax = plt.subplots()
circle = plt.Circle(center, radius, color='blue', fill=False, linestyle='--', label='Circle')
line = plt.Line2D([line_coords[0][0], line_coords[1][0]], [line_coords[0][1], line_coords[1][1]], color='red',
                  label='Line Segment')

ax.add_artist(circle)
ax.add_artist(line)
ax.set_xlim(-10, 100)
ax.set_ylim(-10, 100)
ax.set_aspect('equal', 'box')
plt.title(f'Circle and Line Segment Intersection: {result}')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.grid(True)
plt.show()
